package controllers

import (
	"database/sql"
	"fmt"
	"gitee.com/goblog2/models"
	"gitee.com/goblog2/pkg"
	"github.com/gorilla/mux"
	"html/template"
	"net/http"
	"unicode/utf8"
)

type Article = models.Article

type ArticleController struct {
	*Controller
}

var tmplDir = "resources/compiled_views/"

func (a *ArticleController) Index(w http.ResponseWriter, r *http.Request) {
	rows, err := a.DB.Query("SELECT * FROM articles ORDER BY id DESC")
	pkg.CheckError(err)
	defer rows.Close()
	articles := []Article{}
	for rows.Next() {
		article := Article{}
		rows.Scan(&article.ID, &article.Title, &article.Body)
		articles = append(articles, article)
	}
	pkg.CheckError(rows.Err())
	template.Must(template.ParseFiles(tmplDir+"articles/index.gohtml")).ExecuteTemplate(w, "articles/index.gohtml", articles)
}
func (a *ArticleController) Create(w http.ResponseWriter, r *http.Request) {
	createUrl, _ := a.Router.Get("articles.store").URL()
	tmpl, _ := template.ParseFiles(tmplDir+"articles/create.gohtml", tmplDir+"articles/form.gohtml")
	err := tmpl.ExecuteTemplate(w, "articles/create.gohtml", map[string]interface{}{"URL": createUrl})
	pkg.CheckError(err)
}
func (a *ArticleController) Store(w http.ResponseWriter, r *http.Request) {
	title := r.PostFormValue("title")
	body := r.PostFormValue("body")
	errors := map[string]string{}
	if l := utf8.RuneCountInString(title); l == 0 {
		errors["title"] = "标题不能为空"
	} else if l < 3 || l > 40 {
		errors["title"] = "标题长度需大于两个字符，且小于 40 个字符"
	}
	if l := utf8.RuneCountInString(body); l == 0 {
		errors["body"] = "内容不能为空"
	} else if l < 5 {
		errors["body"] = "字数太少"
	}
	if len(errors) > 0 {
		storeUrl, _ := a.Router.Get("articles.store").URL()
		data := models.ArticleFormData{
			Title:  title,
			Body:   body,
			Errors: errors,
			URL:    storeUrl,
		}
		tmpl, _ := template.ParseFiles(tmplDir + "articles/create.gohtml")
		err := tmpl.ExecuteTemplate(w, "articles/create.gohtml", data)
		pkg.CheckError(err)
	} else {
		id := a.saveArticleToDb(title, body)
		fmt.Fprintf(w, "文章已保存，id = %d", id)
	}
}
func (a *ArticleController) saveArticleToDb(title string, body string) int64 {
	sql := "insert into articles(title, body) values (?, ?)"
	stmt, err := a.DB.Prepare(sql)
	pkg.CheckError(err)
	defer stmt.Close()
	rs, err2 := stmt.Exec(title, body)
	pkg.CheckError(err2)
	id, err3 := rs.LastInsertId()
	pkg.CheckError(err3)
	return id
}
func (a *ArticleController) Show(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]
	article := Article{}
	err := a.DB.QueryRow("SELECT * FROM articles WHERE id=?", id).Scan(&article.ID, &article.Title, &article.Body)
	if err != nil {
		if err == sql.ErrNoRows {
			a.Router.NotFoundHandler.ServeHTTP(w, r)
			return
		} else {
			w.WriteHeader(http.StatusInternalServerError)
			fmt.Fprintf(w, "500 Internal Server Error")
		}
	} else {
		tmpl, err := template.ParseFiles(tmplDir + "articles/show.gohtml")
		pkg.CheckError(err)
		err = tmpl.ExecuteTemplate(w, "articles/show.gohtml", article)
		pkg.CheckError(err)
	}
}
func (a *ArticleController) Edit(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	id := vars["id"]
	article := Article{}
	err := a.DB.QueryRow("select * from articles where id=?", id).Scan(&article.ID, &article.Title, &article.Body)
	pkg.CheckError(err)
	tmpl, _ := template.ParseFiles(tmplDir+"articles/create.gohtml", tmplDir+"articles/form.gohtml")
	err2 := tmpl.ExecuteTemplate(w, "articles/create.gohtml", article)
	pkg.CheckError(err2)
}
func (a *ArticleController) Update(w http.ResponseWriter, r *http.Request)  {}
func (a *ArticleController) Destroy(w http.ResponseWriter, r *http.Request) {}
